﻿using System;
using System.IO;
using UnityEngine;

/// <summary>
/// 文件加载器
/// </summary>
public class FileLoader
{
    public enum FILE_MODE
    {
        TYPED_UNKOWN = 0,
        TYPED_READ_ONLY,           // 原生读
        TYPED_CLEAR_WRITE,         // 清除写
        TYPED_APPEND_WRITE,        // 附加写
        TYPED_READ_CLEAR_WRITE,    // 清除读写
        TYPED_READ_APPEND_WRITE,   // 附加读写
    };

    private FILE_MODE m_OptrMode = FILE_MODE.TYPED_UNKOWN;// 读写操作类型
    private FileStream m_FileStream;        // 文件流对象
    private BinaryWriter m_FileWriter;      // 文件写操作器
    private BinaryReader m_FileReader;      // 文件读操作器

    // 得到当前操作类型
    public FILE_MODE Type()
    {
        return m_OptrMode;
    }

    // 得到当前文件大小
    public long Length()
    {
        if (m_FileStream == null)
        {
            return 0;
        }

        try
        {
            return m_FileStream.Length;
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
        }
        return -1;
    }

    // 加载文件
    public bool Load(string fileName, FILE_MODE mode)
    {
        bool ret = false;
        try
        {
            do
            {
                if (mode == FILE_MODE.TYPED_APPEND_WRITE)
                {
                    m_FileStream = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
                    if (m_FileStream == null) { break; }
                    m_FileWriter = new BinaryWriter(m_FileStream);
                }
                else if (mode == FILE_MODE.TYPED_CLEAR_WRITE)
                {
                    m_FileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
                    if (m_FileStream == null) { break; }
                    m_FileWriter = new BinaryWriter(m_FileStream);
                }
                else if (mode == FILE_MODE.TYPED_READ_APPEND_WRITE)
                {
                    m_FileStream = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
                    if (m_FileStream == null) { break; }
                    m_FileWriter = new BinaryWriter(m_FileStream);
                }
                else if (mode == FILE_MODE.TYPED_READ_CLEAR_WRITE)
                {
                    m_FileStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
                    if (m_FileStream == null) { break; }

                    m_FileWriter = new BinaryWriter(m_FileStream);
                    m_FileReader = new BinaryReader(m_FileStream);
                }
                else if (mode == FILE_MODE.TYPED_READ_ONLY)
                {
                    m_FileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    if (m_FileStream == null) { break; }
                    m_FileReader = new BinaryReader(m_FileStream);
                }
                else { break; }
                ret = true;
            }
            while (false);
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
            ret = false;
        }
        return ret;
    }

    // 卸载操作
    public void UnLoad()
    {
        try
        {
            if (m_FileReader != null)
            {
                m_FileReader.Close();
                m_FileReader = null;
            }

            if (m_FileWriter != null)
            {
                m_FileWriter.Close();
                m_FileWriter = null;
            }

            if (m_FileStream != null)
            {
                m_FileStream.Close();
                m_FileStream = null;
            }
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
        }
    }

    // 设置当前文件的操作指针位置
    public bool Seek(long pos)
    {
        if (m_FileStream == null)
        {
            return false;
        }
        try
        {
            m_FileStream.Seek(0, SeekOrigin.Begin);
            return true;
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
        }
        return false;
    }

    // 读取字节
    public int Read(ref byte[] buffer, int size)
    {
        if (m_FileReader == null)
        {
            return 0;
        }
        try
        {
            buffer = new byte[size];
            return m_FileReader.Read(buffer, 0, size);
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
        }
        return -1;
    }

    // 写字符串
    public bool Write(string text)
    {
        if (m_FileWriter == null)
        {
            return false;
        }
        try
        {
            m_FileWriter.Write(text);
            return true;
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
        }
        return false;
    }

    // 写字节
    public bool Write(byte[] buffer, int size)
    {
        if (m_FileWriter == null)
        {
            return false;
        }
        try
        {
            m_FileWriter.Write(buffer, 0, size);
            return true;
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
        }
        return false;
    }

    // 强制回写文件
    public bool Flush()
    {
        if (m_FileWriter == null)
        {
            return false;
        }
        try
        {
            m_FileWriter.Flush();
            return true;
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
        }
        return false;
    }
}